#include <iostream>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>

int main1() {
    pid_t pid = fork(); // 创建子进程

    if (pid < 0) 
    {
        std::cerr << "fork error" << std::endl;
        return 1;
    } 
    else if (pid == 0) { // 子进程代码
        std::cout << "child process: I am the child process" << std::endl;
        sleep(5); // 子进程等待5秒
        std::cout << "Child process is done" << std::endl;
        return 42; // 子进程结束并返回退出码 42
    } 
    else
    { // 父进程代码
        std::cout << "parent process: I am the parent process" << std::endl;

        sleep(2); // 等待2秒，确保子进程已经开始执行

        // 向子进程发送 SIGQUIT 信号（终止信号）
        int result = kill(pid, SIGQUIT);
        if (result == 0) 
            std::cout << "发送SIGQUIT信号给子进程" << std::endl; 
        else 
            std::cerr << "发送SIGQUIT信号失败" << std::endl;

        int status;
        waitpid(pid, &status, 0); // 等待子进程结束

        // 分析
        if (WIFEXITED(status))  // 检查子进程退出状态
        {
            std::cout << "子进程正常退出，状态为: " << WEXITSTATUS(status) << std::endl;
        } else if (WIFSIGNALED(status))  // 检查是否被信号终止
        {
            std::cout << "子进程被信号终止 " << WTERMSIG(status) << std::endl;
            if (WCOREDUMP(status)) {
                std::cout << "子进程接收到信号，异常终止" << std::endl;
            }
        }
    }

    return 0;
}

int main2()
{
    pid_t pid = fork();
    if(pid == 0)
    {
        // 子进程
        execlp("ls", "ls", "-l", "-a", nullptr); // 替换子进程的映像为ls
        
        // 如果execlp()执行成功，以下代码将不会执行
        // 如果发生错误，execlp()会返回-1
        std::cout << "execlp() / 程序替换失败" << std::endl;
    }
    else if(pid > 0)
    {
        // 父进程
        wait(nullptr); // 等待子进程执行完毕
        std::cout << "子进程退出" << std::endl;
    }
    else
    {
        perror("fork error");
        return 1;
    }

    return 0;
}

// 程序获取进程status
int main3() {
    pid_t id = fork();

    if (id == -1) {
        // 创建子进程失败
        perror("fork");
        exit(EXIT_FAILURE);
    } else if (id == 0) {
        // 子进程
        printf("子进程正在运行\n");
        exit(10);  // 子进程退出状态设为 10
    } else {
        // 父进程
        int status;
        
        pid_t iid = waitpid(id, &status, 0);
        printf("After the wait function\n");
        if(iid == id)
        {
            printf("wait success, pid: %d, status: %d\n", iid, status);
        }
        sleep(10);
    }

    return 0;
}

// 进程阻塞等待
int main4()
{
    pid_t id = fork();

    if(id < 0) {
        // fork error
        perror("fork error");
        exit(EXIT_FAILURE);
    }
    else if(id == 0) {
        // 子进程
        std::cout << "子进程正在运行, pid: " << getpid() << std::endl;
        exit(10);
    }
    else{
        // 父进程
        int status;
        pid_t rid = waitpid(id, &status, 0); // 阻塞等待，options设为0
        std::cout << "after wait" <<std::endl;
        if(rid == id && WIFEXITED(status))
        {
            std::cout << "wait success, pid: " << rid << ", status: " << status << std::endl;
        }
        else
        {
            std::cout << "子进程等待失败, return." << std::endl;
            return 1;
        }
        sleep(10);
    }
    return 0;
}


// 进程非阻塞等待
int main()
{
    pid_t id = fork();
    if(id < 0){
        // error
        perror("fork erorr");
        exit(EXIT_FAILURE);
    }else if(id == 0){
        printf("子进程正在运行，pid:%d \n", getpid());
        exit(10);
    }else{
        int status;

        pid_t rid;
        do{ // 有子进程退出时 rid返回其pid
            pid_t rid = waitpid(id, &status, )
            if(rid == 0)
            {
                printf("child process is running\n");
            }
            sleep(5);
        }while(rid == 0);
        
        if(rid == id && WIFEXITED(status))
        {
            printf("wait success, child return code is :%d.\n",WEXITSTATUS(status));
        }else{
            printf("wait child failed, return.\n");
            return 1;
        }
    }

    return 0;
}